<!-- summary
  目标：仅通过传入data属性（等价于echarts的dataset），即可实现图表渲染，而无需关心其他配置，但支持配置覆盖。
-->
<template>
  <div class="chart" :style="{ height: toCssVal(height), width: toCssVal(width) }" ref="chartRef" />
</template>

<script lang="ts" setup>
import { useEvent } from "@/hooks";
import { ref, nextTick, watch, onMounted } from "vue";
import echarts, { colors } from "./_config";
import { printLog, toCssVal } from "@/core/utils";
import type { EchartTheme } from "./_types";
import { CommonObj } from "@/core/_types";

let echartInstance: any = null;
const chartRef = ref<HTMLElement | null>(null);
const props = withDefaults(
  defineProps<{
    height?: string | number;
    width?: string | number;
    theme?: EchartTheme;
    option?: CommonObj;
    renderer?: "canvas" | "svg";
    log?: boolean | string; // 是否打印options
    use?: any[];
  }>(),
  {
    height: "300px",
    width: "100%",
    theme: "macarons",
    option: () => {
      return {
        title: {
          text: "ECharts 入门示例",
        },
        tooltip: {},
        xAxis: {
          data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"],
        },
        yAxis: {},
        series: [
          {
            name: "销量",
            type: "bar",
            data: [5, 20, 36, 10, 10, 20],
          },
        ],
      };
    },
  }
);
useEvent("resize", () => echartInstance.resize(), false, 200);
let currOptions: CommonObj = {};
watch(
  () => props.option,
  newVal => drawChart(newVal),
  { deep: true }
);
if (props.use) echarts.use(props.use);
function drawChart(option: CommonObj) {
  currOptions = Object.assign({ color: colors }, option);
  const { log } = props;
  if (log) {
    const label = log === true ? "options" : `${log}options`;
    printLog(currOptions, "log", label);
  }
  // notMerge 可选。是否不跟之前设置的 option 进行合并。默认为 false。即表示合并。合并的规则，详见 组件合并模式。如果为 true，表示所有组件都会被删除，然后根据新 option 创建所有新组件。
  // setOption 见 https://echarts.apache.org/zh/api.html#echartsInstance.setOption
  echartInstance.setOption(currOptions, true);
}
onMounted(() => {
  nextTick(() => {
    const { theme, option, renderer } = props;
    echartInstance = echarts.init(chartRef.value, theme, { renderer }); // 初始化 echartInstance 实例
    drawChart(option);
  });
});
defineExpose({
  getWidth() {
    if (!chartRef.value) return null;
    const { clientHeight, clientWidth } = chartRef.value;
    return { height: clientHeight, width: clientWidth };
  },
  getOptions() {
    return currOptions;
  },
});
</script>
<style lang="scss" scoped></style>
